/* DwrPrintWriter.java
 *
 * Copyright 2006, Tim Dwelle.
 *
 * Licensed under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in
 * compliance with the License.  You may obtain a copy of
 * the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in
 * writing, software distributed under the License is
 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
 * CONDITIONS OF ANY KIND, either express or implied.  See
 * the License for the specific language governing
 * permissions and limitations under the License.
 *
 */

package dowry.dwr;

import java.io.*;

/**
 * DwrPrintWriter is a wrapper to the actual servlet
 * print writer, allowing us to inspect the data DWR writes
 * to detect whether an error is being marshalled to the
 * client.
 *
 */
public class DwrPrintWriter extends PrintWriter
{
    public static String ERROR_TEXT = "DWREngine._handleServerError(";

    private boolean err = false;
    private StringWriter sw = null;

    /**
     * Construct a wrapper to the provided print writer
     * instance.
     *
     */
    public DwrPrintWriter()
    {
        this(new StringWriter());
    }

    /**
     * Construct a wrapper to the provided string writer
     * instance.
     *
     * @param sw  the string writer to cache our output
     *
     */
    private DwrPrintWriter(StringWriter sw)
    {
        super(sw);
        this.sw = sw;
    }

    /**
     * Don't actually print anything until the commit is
     * called.  Since we are not wrapping every overloaded
     * version of <code>print()</code>, this could be ugly
     * if not used carefully!
     *
     * @param pw  the actual servlet request's print writer
     *            to be printed to
     *
     */
    public void commit(PrintWriter pw)
    {
        pw.print(sw.toString());
    }

    /**
     * On <code>print()</code>, detect whether or not the
     * string represents the marshalling of an error to the
     * client.
     *
     * @param s  the string to print
     *
     */
    public void print(String s)
    {
        super.print(s);

        if (s.indexOf(ERROR_TEXT) > -1)
        {
            err = true;
        }
    }

    /**
     * Returns whether or not DWR has written an error.
     *
     * @return   true if an error was detected; false
     *           otherwise
     *
     */
    public boolean isError()
    {
        return err;
    }

    /**
     * Manually resets the error flag for this response,
     * as returned by <code>isError()</code>, to the
     * specified value.  Note that it is possible to call to
     * <code>setError(false)</code> and still have
     * <code>isError()</code> return <code>true</code>, if
     * an error is detected after the error flag is set, but
     * before it is read again.
     *
     * @param b  the boolean error condition to set
     *           the response to
     *
     */
    public void setError(boolean b)
    {
        err = b;
    }
}